home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJINC106.ARJ / STREAMBU.H < prev    next >
C/C++ Source or Header  |  1992-03-29  |  12KB  |  344 lines

  1. //    This is part of the iostream library, providing -*- C++ -*- input/output.
  2. //    Copyright (C) 1991 Per Bothner.
  3. //
  4. //    This library is free software; you can redistribute it and/or
  5. //    modify it under the terms of the GNU Library General Public
  6. //    License as published by the Free Software Foundation; either
  7. //    version 2 of the License, or (at your option) any later version.
  8. //
  9. //    This library is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. //    Library General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU Library General Public
  15. //    License along with this library; if not, write to the Free
  16. //    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #ifndef _STREAMBUF_H
  19. #define _STREAMBUF_H
  20. #ifdef __GNUG__
  21. #pragma interface
  22. #endif
  23.  
  24. #include <_G_config.h>
  25. #ifndef fpos_t
  26. #define fpos_t _G_fpos_t
  27. #endif
  28.  
  29. #ifndef EOF
  30. #define EOF (-1)
  31. #endif
  32. #ifndef NULL
  33. #define NULL ((void*)0)
  34. #endif
  35. #ifndef BUFSIZ
  36. #define BUFSIZ 4096
  37. #endif
  38.  
  39. class ostream; class streambuf;
  40.  
  41. typedef long streamoff, streampos;
  42.  
  43. struct _ios_fields { // The data members of an ios.
  44.     streambuf *_strbuf;
  45.     ostream* _tie;
  46.     int _width;
  47.     unsigned long _flags;
  48.     char _fill;
  49.     unsigned char _state;
  50.     unsigned short _precision;
  51. };
  52.  
  53. #define _IOS_GOOD    0
  54. #define _IOS_EOF    1
  55. #define _IOS_FAIL    2
  56. #define _IOS_BAD    4
  57.  
  58. #define _IOS_INPUT    1
  59. #define _IOS_OUTPUT    2
  60. #define _IOS_ATEND    4
  61. #define _IOS_APPEND    8
  62. #define _IOS_TRUNC    16
  63. #define _IOS_NOCREATE    32
  64. #define _IOS_NOREPLACE    64
  65.  
  66. #ifdef _STREAM_COMPAT
  67. enum state_value {
  68.     _good = _IOS_GOOD,
  69.     _eof = _IOS_EOF,
  70.     _fail = _IOS_FAIL,
  71.     _bad = _IOS_BAD };
  72. enum open_mode {
  73.     input = _IOS_INPUT,
  74.     output = _IOS_OUTPUT,
  75.     atend = _IOS_ATEND,
  76.     append = _IOS_APPEND };
  77. #endif
  78.  
  79. class ios : public _ios_fields {
  80.   public:
  81.     enum io_state {
  82.     goodbit = _IOS_GOOD,
  83.     eofbit = _IOS_EOF,
  84.     failbit = _IOS_FAIL,
  85.     badbit = _IOS_BAD };
  86.     enum open_mode {
  87.     in = _IOS_INPUT,
  88.     out = _IOS_OUTPUT,
  89.     ate = _IOS_ATEND,
  90.     app = _IOS_APPEND,
  91.     trunc = _IOS_TRUNC,
  92.     nocreate = _IOS_NOCREATE,
  93.     noreplace = _IOS_NOREPLACE };
  94.     enum seek_dir { beg, cur, end};
  95.     enum { skipws=01, left=02, right=04, internal=010,
  96.        dec=020, oct=040, hex=0100,
  97.        showbase=0200, showpoint=0400, uppercase=01000, showpos=02000,
  98.        scientific=04000, fixed=0100000, unitbuf=020000, stdio=040000,
  99.        dont_close=0x80000000 //Don't close streambuf when destroying stream
  100.        };
  101.  
  102.     ostream* tie() const { return _tie; }
  103.     ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
  104.  
  105.     // Methods to change the format state.
  106.     char fill() const { return _fill; }
  107.     char fill(char newf) { char oldf = _fill; _fill = newf; return oldf; }
  108.     unsigned long flags() const { return _flags; }
  109.     unsigned long flags(unsigned long new_val) {
  110.     unsigned long old_val = _flags; _flags = new_val; return old_val; }
  111.     unsigned short precision() const { return _precision; }
  112.     unsigned short precision(int newp) {
  113.     unsigned short oldp = _precision; _precision = (unsigned short)newp;
  114.     return oldp; }
  115.     unsigned long setf(unsigned long val) {
  116.     unsigned long oldbits = _flags;
  117.     _flags |= val; return oldbits; }
  118.     unsigned long setf(unsigned long val, unsigned long mask) {
  119.     unsigned long oldbits = _flags;
  120.     _flags = (_flags & ~mask) | (val & mask); return oldbits; }
  121.     unsigned long unsetf(unsigned long mask) {
  122.     unsigned long oldbits = _flags & mask;
  123.     _flags &= ~mask; return oldbits; }
  124.     int width() const { return _width; }
  125.     int width(int val) { int save = _width; _width = val; return save; }
  126.  
  127.     static const unsigned long basefield;
  128.     static const unsigned long adjustfield;
  129.     static const unsigned long floatfield;
  130.  
  131.     streambuf* rdbuf() const { return _strbuf; }
  132.     void clear(int state = 0) { _state = state; }
  133.     int good() const { return _state == 0; }
  134.     int eof() const { return _state & ios::eofbit; }
  135.     int fail() const { return _state & (ios::badbit|ios::failbit); }
  136.     int bad() const { return _state & ios::badbit; }
  137.     int rdstate() const { return _state; }
  138.     void set(int flag) { _state |= flag; }
  139.     operator void*() const { return fail() ? (void*)0 : (void*)this; }
  140.     int operator!() const { return fail(); }
  141.  
  142. #ifdef _STREAM_COMPAT
  143.     void unset(state_value flag) { _state &= ~flag; }
  144.     void close();
  145.     int is_open();
  146.     int readable();
  147.     int writable();
  148. #endif
  149.  
  150.   protected:
  151.     ios(streambuf*sb) { _strbuf=sb; _state=0; _width=0; _fill=' ';
  152.             _flags=ios::skipws; _precision=6; }
  153. };
  154.  
  155. #if __GNUG__==1
  156. typedef int _seek_dir;
  157. #else
  158. typedef ios::seek_dir _seek_dir;
  159. #endif
  160.  
  161. // Magic numbers and bits for the _flags field.
  162. // The magic numbers use the high-order bits of _flags;
  163. // the remaining bits are abailable for variable flags.
  164. // Note: The magic numbers must all be negative if stdio
  165. // emulation is desired.
  166.  
  167. #define _IO_MAGIC 0xFBAD0000 /* Magic number */
  168. #define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
  169. #define _IO_MAGIC_MASK 0xFFFF0000
  170. #define _S_USER_BUF 1 /* User owns buffer; don't delete it on close. */
  171. #define _S_UNBUFFERED 2
  172. #define _S_CAN_READ 4
  173. #define _S_CAN_WRITE 8
  174. #define _S_EOF_SEEN 16
  175. #define _S_ERR_SEEN 32
  176. #define _S_DELETE_DONT_CLOSE 64
  177. #define _S_LINKED 128 // Set if linked (using _chain) to streambuf::_list_all.
  178. #define _S_LINE_BUF 0x4000
  179. #define _S_IS_FILEBUF 0x8000
  180.  
  181. #if 0
  182. // A streammarker remembers a position in a buffer.
  183. // You are guaranteed to be able to seek back to it.
  184. class streammarker {
  185.     struct streammarker *_next;
  186.     streambuf *_buf;
  187.     char *_pos; ???
  188.   public:
  189.     streammarker(streambuf *sb);
  190.     ~streamarker();
  191. };
  192. #endif
  193.  
  194. struct __streambuf {
  195.     // NOTE: If this is changed, also change __FILE in stdio/stdio.h!
  196.     int _flags;        /* High-order word is _IO_MAGIC; rest is flags. */
  197.     char* _gptr;    /* Current get pointer */
  198.     char* _egptr;    /* End of get area. */
  199.     char* _eback;    /* Start of putback+get area. */
  200.     char* _pbase;    /* Start of put area. */
  201.     char* _pptr;    /* Current put pointer. */
  202.     char* _epptr;    /* End of put area. */
  203.     char* _base;    /* Start of reserve area. */
  204.     char* _ebuf;    /* End of reserve area. */
  205.     struct streambuf *_chain;
  206. #if 0 // Work in progress
  207.     int _collumn; // Current collumn in line at _pbase; -1 if unknown.
  208.     streammarker *_markers;
  209. #endif
  210. };
  211.  
  212. struct streambuf : private __streambuf {
  213.     friend class ios;
  214.     friend class istream;
  215.     friend class ostream;
  216.   protected:
  217.     static streambuf* _list_all; /* List of open streambufs. */
  218.     streambuf*& xchain() { return _chain; }
  219.     void _un_link();
  220.     void _link_in();
  221.     char* gptr() const { return _gptr; }
  222.     char* pptr() const { return _pptr; }
  223.     char* egptr() const { return _egptr; }
  224.     char* epptr() const { return _epptr; }
  225.     char* pbase() const { return _pbase; }
  226.     char* eback() const { return _eback; }
  227.     char* ebuf() const { return _ebuf; }
  228.     char* base() const { return _base; }
  229.     void xput_char(char c) { *_pptr++ = c; }
  230.     int xflags() { return _flags; }
  231.     int xflags(int f) { int fl = _flags; _flags = f; return fl; }
  232.     void xsetflags(int f) { _flags |= f; }
  233.     void gbump(int n) { _gptr += n; }
  234.     void pbump(int n) { _pptr += n; }
  235.     void setb(char* b, char* eb, int a=0);
  236.     void setp(char* p, char* ep) { _pbase=_pptr=p; _epptr=ep; }
  237.     void setg(char* eb, char* g, char *eg) { _eback=eb; _gptr=g; _egptr=eg; }
  238.   public:
  239.     static int flush_all();
  240.     static void flush_all_linebuffered(); // Flush all line buffered files.
  241.     virtual int underflow(); // Leave public for now
  242.     virtual int overflow(int c = EOF); // Leave public for now
  243.     virtual int doallocate();
  244.     virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
  245.     virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
  246.     int sputbackc(char c);
  247.     int sungetc();
  248.     streambuf();
  249.     virtual ~streambuf();
  250.     int unbuffered() { return _flags & _S_UNBUFFERED ? 1 : 0; }
  251.     int linebuffered() { return _flags & _S_LINE_BUF ? 1 : 0; }
  252.     void unbuffered(int i)
  253.     { if (i) _flags |= _S_UNBUFFERED; else _flags &= ~_S_UNBUFFERED; }
  254.     void linebuffered(int i)
  255.     { if (i) _flags |= _S_LINE_BUF; else _flags &= ~_S_LINE_BUF; }
  256.     int allocate() {
  257.     if (base() || unbuffered()) return 0;
  258.     else return doallocate(); }
  259.     virtual int sync();
  260.     virtual int pbackfail(int c);
  261.     virtual int ungetfail();
  262.     virtual streambuf* setbuf(char* p, int len);
  263.     int in_avail() { return _egptr - _gptr; }
  264.     int out_waiting() { return _pptr - _pbase; }
  265.     virtual int sputn(const char* s, int n);
  266.     virtual int sgetn(char* s, int n);
  267.     long sgetline(char* buf, _G_size_t n, char delim, int putback_delim);
  268.     int sbumpc() {
  269.     if (_gptr >= _egptr && underflow() == EOF) return EOF;
  270.     else return *(unsigned char*)_gptr++; }
  271.     int sgetc() {
  272.     if (_gptr >= _egptr && underflow() == EOF) return EOF;
  273.     else return *(unsigned char*)_gptr; }
  274.     int snextc() {
  275.     if (++_gptr >= _egptr && underflow() == EOF) return EOF;
  276.     else return *(unsigned char*)_gptr; }
  277.     int sputc(int c) {
  278.     if (_pptr >= _epptr) return overflow(c);
  279.     return *_pptr++ = c, (unsigned char)c; }
  280.     int vscan(char const *fmt0, _G_va_list ap);
  281.     int vform(char const *fmt0, _G_va_list ap);
  282. #if 0 /* Work in progress */
  283.     int collumn();  // Current collumn number (of put pointer). -1 is unknown.
  284.     void collumn(int c);  // Set collumn number of put pointer to c.
  285.     friend extern "C" int _handle_overflow(int c);
  286.     friend class streammarker;
  287. #endif
  288. };
  289.  
  290. struct __file_fields {
  291.     char _fake;
  292.     char _shortbuf[1];
  293.     short _fileno;
  294.     int _blksize;
  295.     char* _save_gptr;
  296.     char* _save_egptr;
  297.     fpos_t _offset;
  298. };
  299.  
  300. class filebuf : public streambuf {
  301.     struct __file_fields _fb;
  302.     void init();
  303.   public:
  304.     filebuf();
  305.     filebuf(int fd);
  306.     filebuf(int fd, char* p, int len);
  307.     ~filebuf();
  308.     filebuf* attach(int fd);
  309.     filebuf* open(const char *filename, const char *mode);
  310.     filebuf* open(const char *filename, int mode, int prot = 0664);
  311.     virtual int underflow();
  312.     virtual int overflow(int c = EOF);
  313.     int is_open() { return _fb._fileno >= 0; }
  314.     int fd() { return is_open() ? _fb._fileno : EOF; }
  315.     filebuf* close();
  316.     virtual int doallocate();
  317.     virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
  318.     int sputn(const char* s, int n);
  319.     int sgetn(char* s, int n);
  320.     virtual int sync();
  321.   protected: // See documentation in filebuf.C.
  322.     virtual int pbackfail(int c);
  323.     int is_reading() { return eback() != egptr(); }
  324.     char* cur_ptr() { return is_reading() ?  gptr() : pptr(); }
  325.     /* System's idea of pointer */
  326.     char* file_ptr() { return _fb._save_gptr ? _fb._save_egptr : egptr(); }
  327.     int do_flush();
  328.     // Low-level operations (Usually invoke system calls.)
  329.     virtual int sys_read(char* buf, _G_size_t size);
  330.     virtual fpos_t sys_seek(fpos_t, _seek_dir);
  331.     virtual long sys_write(const void*, long);
  332.     virtual int sys_stat(void*); // Actually, a (struct stat*)
  333.     virtual int sys_close();
  334. };
  335.  
  336. #ifdef _STREAM_COMPAT
  337. inline int ios::readable() { return rdbuf()->_flags & _S_CAN_READ; }
  338. inline int ios::writable() { return rdbuf()->_flags & _S_CAN_WRITE; }
  339. inline int ios::is_open() {return rdbuf()->_flags & _S_CAN_READ+_S_CAN_WRITE;}
  340. #endif
  341.  
  342. #endif /* _STREAMBUF_H */
  343.  
  344.